package com.example.coursehub.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.example.coursehub.service.ClassService;
import org.springframework.http.MediaType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.example.coursehub.entity.*;
import java.util.List;
import java.util.Map;
import java.util.function.ToDoubleBiFunction;

@RestController
@RequestMapping("/api/classes")
public class ClassController {
    @Autowired
    private ClassService classService;

    public void setClassService(ClassService classService) {
        this.classService = classService;
    }
    // 班级基本操作
    /**
     * 创建一个新的班级
     * @param classEntity 要创建的班级对象
     * @return 创建成功后的班级对象及HTTP状态码201（CREATED）
     */
    @PostMapping
    public ResponseEntity<Classes> createClass(@RequestBody Classes classEntity) {
        return new ResponseEntity<>(classService.createClass(classEntity), HttpStatus.CREATED);
    }

    /**
     * 更新一个班级的信息
     * @param classId 要更新的班级的ID
     * @param classEntity 更新后的班级对象
     * @return 更新后的班级对象及HTTP状态码200（OK）
     */
    @PutMapping("/{classId}")
    public ResponseEntity<Classes> updateClass(@PathVariable String classId,
                                                    @RequestBody Classes classEntity) {
        return ResponseEntity.ok(classService.updateClass(classId, classEntity));
    }

    /**
     * 根据班级ID删除一个班级
     * @param classId 要删除的班级的ID
     * @return HTTP状态码204（NO_CONTENT）
     */
    @DeleteMapping("/{classId}")
    public ResponseEntity<Void> deleteClass(@PathVariable String classId) {
        classService.deleteClass(classId);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    /**
     * 根据班级ID获取一个班级
     * @param classId 要获取的班级的ID
     * @return 获取到的班级对象及HTTP状态码200（OK）
     */
    @GetMapping("/{classId}")
    public ResponseEntity<Classes> getClassById(@PathVariable String classId) {
        return ResponseEntity.ok(classService.getClassById(classId));
    }

    /**
     * 根据学生ID获取该学生所在的班级
     * @param userId 学生ID
     * @return 该学生所在的班级对象及HTTP状态码200（OK）
     */
    @GetMapping("/student/{userId}")
    public ResponseEntity<Classes> getClassByStudentId(@PathVariable String userId) {
        return ResponseEntity.ok(classService.getClassByStudentId(userId));
    }

    /**
     * 根据教师ID获取该教师所在的班级
     * @param userId 教师ID
     * @return 该教师所在的班级对象及HTTP状态码200（OK）
     */
    @GetMapping("/teacher/{userId}")
    public ResponseEntity<Classes> getClassByTeacherId(@PathVariable String userId) {
        return ResponseEntity.ok(classService.getClassByTeacherId(userId));
    }

    /**
     * 获取所有班级
     * @return 所有班级的列表及HTTP状态码200（OK）
     */
    
    @GetMapping
    public ResponseEntity<List<Classes>> getAllClasses() {
        try{
        List<Classes> classes = classService.getAllClasses();
        ObjectMapper mapper = new ObjectMapper();
        String jsonOutput = mapper.writeValueAsString(classes);
        return ResponseEntity.ok(classes);
        }
        catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Failed to get classes", e); 
        }
    }
    
    // 班级成员管理
    /**
     * 将一个学生添加到指定班级
     * @param classId 班级ID
     * @param userId 学生ID
     * @return HTTP状态码200（OK）
     */
    @PostMapping("/{classId}/students/{userId}")
    public ResponseEntity<Void> addStudentToClass(@PathVariable String classId, 
                                                  @PathVariable String userId) {
        classService.addStudentToClass(classId, userId);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 将一个学生从指定班级移除
     * @param classId 班级ID
     * @param userId 学生ID
     * @return HTTP状态码200（OK）
     */
    @DeleteMapping("/{classId}/students/{userId}")
    public ResponseEntity<Void> removeStudentFromClass(@PathVariable String classId, 
                                                       @PathVariable String userId) {
        classService.removeStudentFromClass(classId, userId);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 将一个教师添加到指定班级
     * @param classId 班级ID
     * @param userId 教师ID
     * @return HTTP状态码200（OK）
     */
    @PostMapping("/{classId}/teachers/{userId}")
    public ResponseEntity<Void> addTeacherToClass(@PathVariable String classId, 
                                                  @PathVariable String userId) {
        classService.addTeacherToClass(classId, userId);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 将一个教师从指定班级移除
     * @param classId 班级ID
     * @param userId 教师ID
     * @return HTTP状态码200（OK）
     */
    @DeleteMapping("/{classId}/teachers/{userId}")
    public ResponseEntity<Void> removeTeacherFromClass(@PathVariable String classId, 
                                                       @PathVariable String userId) {
        classService.removeTeacherFromClass(classId, userId);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 将一个教学助理添加到指定班级
     * @param classId 班级ID
     * @param userId 教学助理ID
     * @return HTTP状态码200（OK）
     */
    @PostMapping("/{classId}/assistants/{userId}")
    public ResponseEntity<Void> addTeachingAssistantToClass(@PathVariable String classId, 
                                                           @PathVariable String userId) {
        classService.addTeachingAssistantToClass(classId, userId);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 将一个教学助理从指定班级移除
     * @param classId 班级ID
     * @param userId 教学助理ID
     * @return HTTP状态码200（OK）
     */
    @DeleteMapping("/{classId}/assistants/{userId}")
    public ResponseEntity<Void> removeTeachingAssistantFromClass(@PathVariable String classId, 
                                                                @PathVariable String userId) {
        classService.removeTeachingAssistantFromClass(classId, userId);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 将一个练习添加到指定班级
     * @param classId 班级ID
     * @param exerciseId 练习ID
     * @return HTTP状态码200（OK）
     */
    @PostMapping("/{classId}/exercises/{exerciseId}")
    public ResponseEntity<Void> addExerciseToClass(@PathVariable String classId, 
                                                  @PathVariable String exerciseId) {
        classService.addExerciseToClass(classId, exerciseId);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 将一个练习从指定班级移除
     * @param classId 班级ID
     * @param exerciseId 练习ID
     * @return HTTP状态码200（OK）
     */
    @DeleteMapping("/{classId}/exercises/{exerciseId}")
    public ResponseEntity<Void> removeExerciseFromClass(@PathVariable String classId, 
                                                       @PathVariable String exerciseId) {
        classService.removeExerciseFromClass(classId, exerciseId);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * 获取指定课程和学生的学习记录
     * @param courseId 课程ID
     * @param userId 学生ID
     * @return 学习记录列表及HTTP状态码200（OK）
     */

    /**
     * 获取指定班级的所有教师
     * @param classId 班级ID
     * @return 该班级的所有教师列表及HTTP状态码200（OK）
     */
    @GetMapping("/{classId}/teachers")
    public ResponseEntity<List<User>> getTeachersInClass(@PathVariable String classId) {
        try {
            List<User> teachers = classService.getTeachersInClass(classId);

            ObjectMapper mapper = new ObjectMapper();
            String jsonOutput = mapper.writeValueAsString(teachers);

            return ResponseEntity.ok(teachers);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * 获取指定班级的所有学生
     * @param classId 班级ID
     * @return 该班级的所有学生列表及HTTP状态码200（OK）
     */
    @GetMapping("/{classId}/students")
    public List<User> getStudentsInClass(@PathVariable String classId) {
        List<User> students = classService.getStudentsInClass(classId);
        ObjectMapper mapper = new ObjectMapper();
        try {
           String jsonOutput = mapper.writeValueAsString(students);
        } catch (Exception e) {
          e.printStackTrace();
        }

        return students;
    }

    @GetMapping("/course/{courseId}")
    public ResponseEntity<List<Classes>> getClassesByCourseId(@PathVariable String courseId) {
        return ResponseEntity.ok(classService.getClassesByCourseId(courseId));
    }

    @GetMapping("/course/{courseId}/students/{userId}/joined")
    public ResponseEntity<Boolean> hasJoinedClass(
            @PathVariable String courseId,
            @PathVariable String userId) {
        boolean joined = classService.hasUserJoinedAnyClass(courseId, userId);
        return ResponseEntity.ok(joined);
    }

    @GetMapping("/{userId}/course/{courseId}/members")
    public ResponseEntity<Map<String, List<String>>> getClassMembers(
            @PathVariable String userId,
            @PathVariable String courseId) {
        Map<String, List<String>> members = classService.getClassMembers(userId, courseId);
        return ResponseEntity.ok(members);
    }
    @GetMapping("/teacher/{userId}/course/{courseId}")
    public ResponseEntity<List<Classes>> getClassesByTeacherAndCourse(
            @PathVariable String userId,
            @PathVariable String courseId) {
        try {
            List<Classes> classes = classService.getClassesByTeacherAndCourse(userId, courseId);
            return ResponseEntity.ok(classes);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }

}
